package cn.iocoder.yudao.module.system.service.book;

import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.Map;

/**
 * 绘本上传 Service 接口
 *
 * @author 芋道源码
 */
public interface BookUploadService {

    /**
     * 上传压缩包（临时）
     *
     * @param file 压缩包文件
     * @param sessionUuid 会话UUID
     * @return 上传结果，包含minioObjectUrl和tempKey
     */
    Map<String, String> uploadCompressedFile(MultipartFile file, String sessionUuid) throws IOException;

    /**
     * 上传封面（临时）
     *
     * @param file 封面文件
     * @param sessionUuid 会话UUID
     * @return 上传结果，包含coverUrl和tempKey
     */
    Map<String, String> uploadCoverFile(MultipartFile file, String sessionUuid) throws IOException;

    /**
     * 最终提交处理
     *
     * @param title 绘本名称
     * @param sessionUuid 会话UUID
     * @param compressedTempKey 压缩包tempKey
     * @param coverTempKey 封面tempKey
     * @param minioObjectUrl 压缩包临时URL
     * @param coverUrl 封面临时URL
     * @param formatDescription 格式说明
     * @return 绘本ID
     */
    Long submitBookUpload(String title, String sessionUuid, String compressedTempKey, 
                         String coverTempKey, String minioObjectUrl, String coverUrl, 
                         String formatDescription);

    /**
     * 清理过期的临时文件
     */
    void cleanupExpiredTempFiles();

    /**
     * 校验会话UUID是否有效
     *
     * @param sessionUuid 会话UUID
     * @return 是否有效
     */
    boolean validateSessionUuid(String sessionUuid);

    /**
     * 校验tempKey是否有效
     *
     * @param sessionUuid 会话UUID
     * @param tempKey tempKey
     * @param type 类型（compressed/cover）
     * @return 是否有效
     */
    boolean validateTempKey(String sessionUuid, String tempKey, String type);

    /**
     * 生成临时访问URL
     *
     * @param path 文件路径
     * @param expireMinutes 过期时间（分钟）
     * @return 临时URL
     */
    String generateTempUrl(String path, int expireMinutes);

    /**
     * 生成tempKey
     *
     * @param sessionUuid 会话UUID
     * @param type 类型
     * @return tempKey
     */
    String generateTempKey(String sessionUuid, String type);

    /**
     * 存储tempKey到Redis
     *
     * @param sessionUuid 会话UUID
     * @param tempKey tempKey
     * @param type 类型
     * @param minioPath MinIO路径
     */
    void storeTempKey(String sessionUuid, String tempKey, String type, String minioPath);

    /**
     * 从Redis获取tempKey信息
     *
     * @param sessionUuid 会话UUID
     * @return tempKey信息Map
     */
    Map<String, Object> getTempKeyInfo(String sessionUuid);

    /**
     * 删除Redis中的tempKey信息
     *
     * @param sessionUuid 会话UUID
     */
    void deleteTempKeyInfo(String sessionUuid);

    /**
     * 校验文件格式和大小
     *
     * @param file 文件
     * @param allowedTypes 允许的类型
     * @param maxSizeMB 最大大小（MB）
     * @return 是否有效
     */
    boolean validateFile(MultipartFile file, String[] allowedTypes, int maxSizeMB);

    /**
     * 生成唯一文件名
     *
     * @param originalFilename 原始文件名
     * @param sessionUuid 会话UUID
     * @return 唯一文件名
     */
    String generateUniqueFilename(String originalFilename, String sessionUuid);

    /**
     * 解压压缩包并校验内容
     *
     * @param compressedFilePath 压缩包路径
     * @return 解压后的文件信息
     */
    Map<String, Object> extractAndValidateCompressedFile(String compressedFilePath);

    /**
     * 解析音频时长
     *
     * @param audioFilePath 音频文件路径
     * @return 时长（秒）
     */
    Integer parseAudioDuration(String audioFilePath);

    /**
     * 转存文件到永久路径
     *
     * @param sourcePath 源路径
     * @param targetPath 目标路径
     * @return 是否成功
     */
    boolean transferFile(String sourcePath, String targetPath);

    /**
     * 删除临时文件
     *
     * @param filePath 文件路径
     */
    void deleteTempFile(String filePath);

    /**
     * 校验绘本名称
     *
     * @param title 绘本名称
     * @return 校验结果
     */
    Map<String, Object> validateBookTitle(String title);

    /**
     * 检查幂等性
     *
     * @param sessionUuid 会话UUID
     * @return 是否重复提交
     */
    boolean checkIdempotency(String sessionUuid);

    /**
     * 标记会话为已处理
     *
     * @param sessionUuid 会话UUID
     */
    void markSessionAsProcessed(String sessionUuid);
} 